package com.fliangyun.nsa.nsamanage.controller;

import com.fliangyun.nsa.nsamanage.entities.FileInfo;
import com.fliangyun.nsa.nsamanage.entities.LogInfo;
import com.fliangyun.nsa.nsamanage.entities.User;
import com.fliangyun.nsa.nsamanage.service.impl.LogInfoServiceImpl;
import com.fliangyun.nsa.nsamanage.service.impl.UserServiceImpl;
import com.fliangyun.nsa.nsamanage.utils.FileUtil;
import com.fliangyun.nsa.nsamanage.utils.ImageIoUtil;
import com.fliangyun.nsa.nsamanage.utils.StringUtil;
import com.fliangyun.nsa.nsamanage.web.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author fuliangyun@139.com
 * @date 2023年05月30日
 * @description
 */
@Slf4j
@RestController
@RequestMapping(value = "api")
public class ApiIndexController {
    @Value("${nsa.base.folder}")
    String baseFileFolder;
    private static final String URL = "/file";

    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private LogInfoServiceImpl logInfoService;

    @GetMapping("getFiles")
    public Result<?> getFiles(String path, Integer page, Integer pageSize, Authentication authentication){
        User user = (User) authentication.getPrincipal();
        String base = FileUtil.getPath(baseFileFolder, user.getId());
        path = FileUtil.getPath(base, path);

        pageSize = pageSize == null?15:pageSize;
        page = page == null?1:page;

        // 获取文件列表
        File file = new File(path);
        File[] files = file.listFiles();
        
        List<FileInfo> fileInfoList = new ArrayList<>();
        if (files == null){
            return Result.fail("参数错误");
        }

        for (File f : files) {
            if (f.isHidden()){
                continue;
            }
            FileInfo fileInfo = new FileInfo();
            fileInfo.setId(StringUtil.uuid());
            fileInfo.setFolder(f.isDirectory());
            String p = FileUtil.getPath(f.getAbsolutePath());
            String url = p.replace(base, FileUtil.getPath(URL, user.getId()));
            String pa = p.replace(base, "");
            fileInfo.setPath(pa.substring(0, pa.lastIndexOf("/")));
            fileInfo.setUrl(url);
            fileInfo.setFileName(p.substring(p.lastIndexOf("/")+1));

            // 获取创建时间
            Path pp = Paths.get(f.getAbsolutePath());
            BasicFileAttributes attrs = null;
            try {
                attrs = Files.readAttributes(pp, BasicFileAttributes.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 从基本属性类中获取文件创建时间
            if (attrs != null){
                FileTime fileTime = attrs.creationTime();
                // 将文件创建时间转成毫秒
                long millis = fileTime.toMillis();
                Date d = new Date();
                d.setTime(millis);
                fileInfo.setCreateTime(d);
            }

            if (fileInfo.isFolder()){
                fileInfo.setPhoto("/common/images/folder.png");
            }else {
                String fn = fileInfo.getFileName().toLowerCase();
                if (fn.endsWith("png")||fn.endsWith("jpg")||fn.endsWith("jpeg")){
                    fileInfo.setPhoto(fileInfo.getUrl());
                    fileInfo.setPicture(true);
                }else {
                    fileInfo.setPhoto("/common/images/file.png");
                }
            }
            fileInfoList.add(fileInfo);
        }

        // 返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("fileInfoList", fileInfoList);
        result.put("currentPath", path.replace(base, ""));
        String currentPath = path.replace(base, "");
        currentPath = currentPath.substring(0, currentPath.lastIndexOf(FileUtil.BIAS));
        result.put("parentPath", currentPath);
        result.put("page", page);
        result.put("pageSize", pageSize);

        // 分页
        if (fileInfoList.size() > 0){
            // 根据创建时间倒叙排序
            fileInfoList = fileInfoList.stream().sorted(Comparator.comparing(FileInfo::getCreateTime).reversed()).collect(Collectors.toList());
            // 分页
            int size = fileInfoList.size();
            int len = size/pageSize;
            result.put("totalPage", len);
            if (page*pageSize>size){
                result.put("fileInfoList", fileInfoList.stream().skip((long) len *pageSize).limit(pageSize));
            }else {
                result.put("fileInfoList", fileInfoList.stream().skip((long) (page-1) *pageSize).limit(pageSize));
            }
//            List<List<FileInfo>> list =
//            if (page<len){
//                int from = (page-1)*pageSize;
//                int to = Math.min(page * pageSize, size);
//                result.put("fileInfoList", fileInfoList.subList(from, to));
//            }else {
//                int from = (len-1)*pageSize;
//                result.put("fileInfoList", fileInfoList.subList(from, size));
//            }
        }
        return Result.success(result);
    }

    /**
     * 修改密码
     * @author fuliangyun@139.com
     * @date 2023-06-01 10:09
     * @param authentication
     * @param para
     * @return Result<?>
     */
    @PostMapping("savePassword")
    public Result<?> savePassword(Authentication authentication, User para){
        if (StringUtil.isBlank(para.getPassword())){
            return Result.fail("密码为空");
        }
        // 获取用户信息
        User user = (User) authentication.getPrincipal();
        user.setPassword(new BCryptPasswordEncoder().encode(para.getPassword()));
        userService.saveUser(user);
        return Result.success("密码修改成功", user);
    }

    /**
     * 修改密码
     * @author fuliangyun@139.com
     * @date 2023-06-01 10:09
     * @param authentication
     * @return Result<?>
     */
    @PostMapping("savePhoto")
    public Result<?> savePhoto(Authentication authentication, MultipartFile file){
        if (file == null){
            return Result.fail("头像图片为空");
        }
        // 获取用户信息
        User user = (User) authentication.getPrincipal();
        String basePath = FileUtil.getPath(baseFileFolder, "photo");
        // 创建文件夹
        FileUtil.createFolder(basePath);

        // 保存图片
        String fileName = System.currentTimeMillis()+".png";
        File photo = new File(FileUtil.getPath(basePath, fileName));
        try {
            file.transferTo(photo);

            // 图片压缩
            String url = photo.getAbsolutePath();
            String suffix = url .substring(url.lastIndexOf(".") + 1);
            ImageIoUtil.compression(url, photo.getAbsolutePath(),1.5,0.1f,0.5f,suffix);
            user.setPhoto(FileUtil.getPath(FileUtil.BIAS,"file", "photo", fileName));
            userService.saveUser(user);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.fail("头像修改失败");
        }
        return Result.success("头像修改成功", user);
    }

    /**
     * 上传文件
     * @author fuliangyun@139.com
     * @date 2023-06-01 10:09
     * @param authentication
     * @return Result<?>
     */
    @PostMapping("uploadFile")
    public Result<?> uploadFile(Authentication authentication, MultipartFile file, String path){
        if (file == null){
            return Result.fail("上传文件为空");
        }
        // 获取用户信息
        User user = (User) authentication.getPrincipal();
        String basePath = FileUtil.getPath(baseFileFolder, user.getId(), path);
        // 保存图片
        String fileName = file.getOriginalFilename();
        File upFile = new File(FileUtil.getPath(basePath, fileName));
        // 创建文件夹
        upFile.mkdirs();
        try {
            file.transferTo(upFile);
            LogInfo logInfo = new LogInfo();
            logInfo.setAction("上传文件");
            logInfo.setDetail(upFile.getAbsolutePath());
            logInfoService.save(logInfo);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.fail("上传失败");
        }
        return Result.success("上传成功");
    }

    /**
     * 创建文件夹
     * @author fuliangyun@139.com
     * @date 2023-06-01 10:09
     * @param authentication
     * @param name
     * @return Result<?>
     */
    @PostMapping("createFolder")
    public Result<?> createFolder(Authentication authentication, String name, String path){
        if (StringUtil.isBlank(name)){
            return Result.fail("文件夹名称不能为空");
        }
        User user = (User) authentication.getPrincipal();
        // 判断文件夹是否存在
        path = FileUtil.getPath(baseFileFolder, user.getId(), path, name);
        File file = new File(path);
        int i = 1;
        while (file.exists()){
            path = path.replace(name, name+"("+(i++)+")");
            file = new File(path);
        }
        file.mkdirs();
        LogInfo logInfo = new LogInfo();
        logInfo.setAction("创建文件夹");
        logInfo.setDetail(path);
        logInfoService.save(logInfo);
        return Result.success("创建成功", null);
    }

}
